package com.eastfair.auth.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.annotation.annotation.base.BaseControllerInfo;
import com.eastfair.annotation.annotation.log.SysLog;
import com.eastfair.annotation.annotation.security.PreAuth;
import com.eastfair.annotation.base.SubjectTypeEnum;
import com.eastfair.annotation.database.mybatis.auth.DataScope;
import com.eastfair.auth.dao.BusinessMapper;
import com.eastfair.auth.dto.*;
import com.eastfair.auth.entity.Organization;
import com.eastfair.auth.entity.Role;
import com.eastfair.auth.entity.UserAccount;
import com.eastfair.auth.entity.UserRole;
import com.eastfair.auth.enumeration.OrganizationOrgTypeEnum;
import com.eastfair.auth.enumeration.OrganizationVestTypeEnum;
import com.eastfair.auth.enumeration.RoleRoleTypeEnum;
import com.eastfair.auth.enumeration.UserAccountStatusEnum;
import com.eastfair.auth.exceptioncode.AuthServiceExceptionCode;
import com.eastfair.auth.messagecenter.BusinessEnum;
import com.eastfair.auth.service.*;
import com.eastfair.auth.util.HuaWeiIamUtil;
import com.eastfair.auth.vo.*;
import com.eastfair.boot.controller.SuperController;
import com.eastfair.boot.request.PageParams;
import com.eastfair.cache.auth.MobileLoginCodeCacheKeyBuilder;
import com.eastfair.cache.projectcore.DictionaryEnabledCacheKeyBuilder;
import com.eastfair.cache.redis.RedisOps;
import com.eastfair.cache.repository.CacheOps;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.context.StaticContextUtil;
import com.eastfair.core.encrypt.RSAEncrypt;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.exception.NoBackBizException;
import com.eastfair.core.exception.code.ExceptionCode;
import com.eastfair.core.model.CacheHashKey;
import com.eastfair.core.model.CacheKey;
import com.eastfair.core.plumelog.CompressMessage;
import com.eastfair.core.utils.HeaderUtil;
import com.eastfair.database.mybatis.conditions.Wraps;
import com.eastfair.database.mybatis.conditions.query.QueryWrap;
import com.eastfair.database.mybatis.typehandler.TypeHandlerUtil;
import com.eastfair.demand.auth.OrganizationVoGroupClass;
import com.eastfair.demand.auth.UserAccountVoGroupClass;
import com.eastfair.echo.core.EchoService;
import com.eastfair.el.ElParam;
import com.eastfair.jwt.model.AuthInfo;
import com.eastfair.jwt.model.JwtUserInfo;
import com.eastfair.jwt.service.JwtService;
import com.eastfair.messagecenter.ContentModel;
import com.eastfair.messagecenter.api.MsgServiceFeign;
import com.eastfair.messagecenter.api.SmsTemplateServiceFeign;
import com.eastfair.messagecenter.dto.InnerSendDTO;
import com.eastfair.messagecenter.dto.SmsSendDTO;
import com.eastfair.messagecenter.dto.SmsTemplateDTO;
import com.eastfair.messagecenter.entity.SmsTemplate;
import com.eastfair.messagecenter.enumeration.ChannelType;
import com.eastfair.messagecenter.model.InnerContentModel;
import com.eastfair.messagecenter.model.SmsContentModel;
import com.eastfair.messagecenter.vo.SmsTemplateVO;
import com.eastfair.model.DataIsolationVo;
import com.eastfair.plumelog.util.LZ4Util;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.projectcore.dto.DataIsolationDTO;
import com.eastfair.projectcore.enumeration.DataIsolationSystemSceneEnum;
import com.eastfair.projectcore.enumeration.MenuAffiliationEnum;
import com.eastfair.projectcore.enumeration.MenuSceneEnum;
import com.eastfair.security.handler.DataIsolactionHandler;
import com.eastfair.security.util.TenantUtil;
import com.eastfair.uid.baidu.rule.SnowFlakeRole;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.runtime.CodeInstaller;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static com.eastfair.core.base.R.SUCCESS_CODE;
import static com.eastfair.core.exception.code.ExceptionCode.*;


/**
 * <p>
 * 前端控制器
 * 用户账户信息
 * </p>
 *
 * @author ligang
 * @date 2021-07-13
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/userAccount")
@Api(value = "UserAccount", tags = "用户账户信息")
@PreAuth(replace = "system:user:")
public class UserAccountController extends SuperController<UserAccountService, Long, UserAccount, UserAccountPageQuery, UserAccountSaveDTO, UserAccountUpdateDTO> {

    @Autowired
    private EchoService echoService;

    @Autowired
    UserAccountService userAccountService;
    @Autowired
    TenantUtil tenantUtil;

    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;

    @Autowired
    OrganizationService organizationService;

    @Autowired
    UserOrganizationService userOrganizationService;


    @Autowired
    UserRoleService userRoleService;

    @Autowired
    RoleService roleService;

    @Autowired
    private RedisOps redisOps;

    @Autowired
    private BusinessMapper businessMapper;

    @Autowired
    DataIsolactionHandler dataIsolactionHandler;

    @Autowired
    MsgServiceFeign msgServiceFeign;

    @Autowired
    SmsTemplateServiceFeign smsTemplateServiceFeign;

    @Autowired
    protected CacheOps cacheOps;

    @Autowired
    HuaWeiIamUtil huaWeiIamUtil;

    @Autowired
    RoleController roleController;

    @Autowired
    JwtService jwtService;

    @Value("${com.eastfair.projectId}")
    private Long commonProjectId;

    @Value("${com.eastfair.permanentToken}")
    private String permanentToken;

    @Autowired
    private SnowFlakeRole snowFlakeRole;

    @Override
    public void handlerResult(IPage<UserAccount> page) {
        // 想让返回值实现自动回显，请将此行代码打开
        // echoService.action(page);
    }


//    /**
//     * 处理参数
//     *
//     * @param params 分页参数
//     */
//    @Override
//    public void handlerQueryParams(PageParams<UserAccountPageQuery> params) {
//        UserAccountPageQuery userAccountPageQuery = params.getModel();
//        if(userAccountPageQuery!=null){
//            Map<String, Object> extraMap = new HashMap<>();
//            if(userAccountPageQuery.getOrgIds()!=null && !userAccountPageQuery.getOrgIds().isEmpty()){
//
//                //查询
//            }
//        }
//        Map<String, Object> extraMap = params.getExtra();
//        if(){
//
//        }
//    }


    /**
     * Excel导入后的操作
     *
     * @param list
     */
    @Override
    public R<Boolean> handlerImport(List<Map<String, String>> list) {
        List<UserAccount> userAccountList = list.stream().map((map) -> {
            UserAccount userAccount = UserAccount.builder().build();
            //TODO 请在这里完成转换
            return userAccount;
        }).collect(Collectors.toList());

        return R.success(baseService.saveBatch(userAccountList));
    }


    /**
     * 注册
     *
     * @param userAccountDto 用户新增实体
     *                       //     * @param sysUser        全局变量实体
     * @return
     */
    @ApiOperation(value = "注册", notes = "注册")
    @PostMapping("/register")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.register.class})
//    public R<UserAccountVo> register(@RequestBody UserAccountDto userAccountDto, @ApiIgnore @LoginUser SysUser sysUser) {
    public R<UserAccountVo> register(@RequestBody UserAccountDto userAccountDto) {
        if (StringUtils.isNotBlank(userAccountDto.getVerifyValue()) && !"9999".equals(userAccountDto.getVerifyValue())) {
            CacheKey key = new MobileLoginCodeCacheKeyBuilder().key(userAccountDto.getMobile());
            String code = cacheOps.get(key);
            if (code == null || !code.equals(userAccountDto.getVerifyValue())) {
                return R.fail(AuthServiceExceptionCode.PHONE_CODE_ERROR);
            }
        }

        //解密
        if (StringUtils.isNotBlank(userAccountDto.getPublicKey())) {
            String privateKey = redisOps.get("privatekey:" + userAccountDto.getPublicKey());
            if (StringUtils.isBlank(privateKey)) {
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
            try {
                userAccountDto.setPassword(RSAEncrypt.decrypt(userAccountDto.getPassword(), privateKey));
                log.info("解密后 login is " + JSON.toJSONString(userAccountDto));
            } catch (Exception e) {
                log.error(e.getMessage());
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
        }

        return userAccountService.register(userAccountDto);
    }

    /**
     * 查询用户是否注册
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "查询用户是否注册", notes = "查询用户是否注册")
    @PostMapping("/queryUserOfregister")
    public R<List<UserAccountVo>> queryUserOfregister(@RequestBody UserAccountDto userAccountDto) {
        return R.success(userAccountService.doToVos(userAccountService.queryUserOfregister(userAccountDto)));
    }


    /**
     * 添加用户
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "添加用户", notes = "添加用户")
    @PostMapping("/saveUser")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.register.class})
    public R<UserAccountVo> saveUser(@RequestBody UserAccountDto userAccountDto) {
        // TODO: 2021/11/2 暂时无需求，和注册一样，但得分开
        return userAccountService.register(userAccountDto);
    }


    /**
     * 用户加入到子系统
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "用户加入到子系统", notes = "用户加入到子系统")
    @PostMapping("/addSubSystemUser")
    public R<UserAccountVo> addSubSystemUser(@RequestBody UserAccountDto userAccountDto) {
        // TODO: 2021/11/2 暂时无需求，和注册一样，但得分开
        return userAccountService.addSubSystemUser(userAccountDto.getId());
    }


    /**
     * 用户注册到子系统 没有token
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "用户注册到子系统 没有token", notes = "用户注册到子系统 没有token")
    @PostMapping("/registerSubSystemUser")
    public R<UserAccountVo> registerSubSystemUser(@RequestBody UserAccountDto userAccountDto) {
        //解密
        if (StringUtils.isNotBlank(userAccountDto.getPublicKey())) {
            String privateKey = redisOps.get("privatekey:" + userAccountDto.getPublicKey());
            if (StringUtils.isBlank(privateKey)) {
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
            try {
                userAccountDto.setPassword(RSAEncrypt.decrypt(userAccountDto.getPassword(), privateKey));
                log.info("解密后 login is " + JSON.toJSONString(userAccountDto));
            } catch (Exception e) {
                log.error(e.getMessage());
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
        }

        //账号替换手机号
        userAccountDto.setName(userAccountDto.getMobile());
        // TODO: 2021/11/2 暂时无需求，和注册一样，但得分开
        List<UserAccount> userAccountList = userAccountService.queryUserOfregister(userAccountDto);
        if (userAccountList == null || userAccountList.isEmpty()) {
            //注册
//            return register(userAccountDto);
            return userAccountService.register(userAccountDto);
        } else {
            //校验验证码
            if (StringUtils.isNotBlank(userAccountDto.getVerifyValue()) && !"9999".equals(userAccountDto.getVerifyValue())) {
                CacheKey key = new MobileLoginCodeCacheKeyBuilder().key(userAccountDto.getMobile());
                String code = cacheOps.get(key);
                if (code == null || !code.equals(userAccountDto.getVerifyValue())) {
                    return R.fail(AuthServiceExceptionCode.PHONE_CODE_ERROR);
                }
            }
            if (userAccountList.size() == 1) {
                Integer isIn = userAccountService.isSubSystem(userAccountList.get(0));
                if (isIn == BusinessConstant.YES) {
                    throw NoBackBizException.wrap(AuthServiceExceptionCode.USER_AGAIN);
                }
                //是本人,加入到子系统
                userAccountDto.setId(userAccountList.get(0).getId());
                return addSubSystemUser(userAccountDto);
            } else {
                //查到多条数据
                for (UserAccount userAccount : userAccountList) {
                    if (userAccount.getName().equals(userAccountDto.getName())) {
                        return R.fail(LOGINNAME_AGAIN);
                    } else if (userAccount.getMobile().equals(userAccountDto.getMobile())) {
                        return R.fail(MOBILE_AGAIN);
                    } else if (userAccount.getEmail().equals(userAccountDto.getEmail())) {
                        return R.fail(EMIAL_AGAIN);
                    }
                }
                return R.fail(LOGINNAME_AGAIN);
            }
        }
    }


    /**
     * 用户注册到子系统
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "用户注册到子系统", notes = "用户注册到子系统")
    @PostMapping("/registerSubSystemUserOfToken")
    public R<UserAccountVo> registerSubSystemUserOfToken(@RequestBody UserAccountDto userAccountDto) {
        // TODO: 2021/11/2 暂时无需求，和注册一样，但得分开
        List<UserAccount> userAccountList = userAccountService.queryUserOfregister(userAccountDto);
        if (userAccountList == null || userAccountList.isEmpty()) {
            //注册
//            return register(userAccountDto);
            return userAccountService.register(userAccountDto);
        } else {
            if (userAccountList.size() == 1) {
                Integer isIn = userAccountService.isSubSystem(userAccountList.get(0));
                if (isIn == BusinessConstant.YES) {
                    Long userTeamId = userAccountService.queryTeamId(userAccountList.get(0));
                    if (userTeamId != null && ContextUtil.getTeamId() != null && !userTeamId.equals(ContextUtil.getTeamId())) {
                        throw NoBackBizException.wrap(AuthServiceExceptionCode.USER_IN_OTHER_TEAM);
                    }
                    throw NoBackBizException.wrap(AuthServiceExceptionCode.USER_IN_SYSTEM);
                }
                //是本人,加入到子系统
                userAccountDto.setId(userAccountList.get(0).getId());
                R<UserAccountVo> accountVoR = addSubSystemUser(userAccountDto);
                //添加到组织里
                if (CollectionUtil.isNotEmpty(userAccountDto.getOrgIds())) {
                    //清空部门
                    userOrganizationService.removeUserOfOrg(Arrays.asList(userAccountDto.getId()));
                    for (Long orgId : userAccountDto.getOrgIds()) {
                        organizationService.addUseridOfOrg(orgId, Arrays.asList(userAccountDto.getId()), userAccountDto.getIsLeader());
                    }
                }
                //修改用户角色
                if (CollectionUtil.isNotEmpty(userAccountDto.getRoleIds())) {
                    userRoleService.updUserRole(Arrays.asList(userAccountDto.getId()), userAccountDto.getRoleIds());
                }
                return accountVoR;
            } else {
                //查到多条数据
                return R.fail("检测到多条数据");
            }
        }
    }

    /**
     * 用户剔除到子系统
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "用户剔除到子系统", notes = "用户剔除到子系统")
    @PostMapping("/removeSubSystemUser")
    public R<UserAccountVo> removeSubSystemUser(@RequestBody UserAccountDto userAccountDto) {
        // TODO: 2021/11/2 暂时无需求，和注册一样，但得分开
        return userAccountService.removeSubSystemUser(userAccountDto.getId());
    }

    /**
     * 添加公司用户
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "添加公司用户", notes = "添加公司用户")
    @PostMapping("/saveCompanyUser")
    public R<UserAccountVo> saveCompanyUser(@RequestBody UserAccountDto
                                                    userAccountDto) {

        // TODO: 2021/11/2 暂时无需求，和注册一样，但得分开
        return userAccountService.registerOfCompany(userAccountDto);
    }

    /**
     * 给项目创建管理员
     *
     * @param userAccountDto 用户新增实体
     * @return
     */
    @ApiOperation(value = "给项目创建管理员", notes = "给项目创建管理员")
    @PostMapping("/addAdminUser")
    public R<UserAccountVo> addAdminUser(@RequestBody UserAccountDto userAccountDto) {
        return userAccountService.addAdminUser(userAccountDto);
    }

    /**
     * 登录
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "登录", notes = "登录")
    @PostMapping("/login")
    @SysLog("登录")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<UserAccountVo> login(@RequestBody UserAccountDto userAccountDto) {
        log.info("login is " + JSON.toJSONString(userAccountDto));
        //解密
        if (StringUtils.isNotBlank(userAccountDto.getPublicKey())) {
            String privateKey = redisOps.get("privatekey:" + userAccountDto.getPublicKey());
            if (StringUtils.isBlank(privateKey)) {
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
            try {
                userAccountDto.setPassword(RSAEncrypt.decrypt(userAccountDto.getPassword(), privateKey));
                log.info("解密后 login is " + JSON.toJSONString(userAccountDto));
            } catch (Exception e) {
                log.error(e.getMessage());
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
        }

        //检验图形验证码
//        if (StringUtils.isBlank(userAccountDto.getVerifyId())) {
//            throw BizException.wrap(ExceptionCode.CAPTCHA_ERROR);
//        }
        if (StringUtils.isNotBlank(userAccountDto.getVerifyId())) {
            String verifyValue = redisOps.get(userAccountDto.getVerifyId());
            if (StringUtils.isBlank(userAccountDto.getVerifyValue())
                    || StringUtils.isBlank(verifyValue)
                    || !userAccountDto.getVerifyValue().equals(verifyValue)) {
                throw BizException.wrap(ExceptionCode.CAPTCHA_ERROR);
            }
        }

        //检验登录必要参数
        R r = verifyLoginParams(userAccountDto);
        if (SUCCESS_CODE != r.getCode()) {
            return r;
        }
        //全库查询用户信息
//        UserAccountDto userAccountDto2 = new UserAccountDto();
//        userAccountDto2.setName(userAccountDto.getName());
//        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
//        if (userAccountList != null && !userAccountList.isEmpty()) {
//            if (BusinessConstant.NO == userAccountList.get(0).getIsEnabled()) {
//                throw BizException.wrap(ExceptionCode.USER_NO_ENABLED);
//            }
//            //设置项目id
//            ContextUtil.setProjectId(userAccountList.get(0).getProjectId());
//            //设置子系统id
////            DataIsolationDTO dataIsolationDTO = new DataIsolationDTO();
////            dataIsolationDTO.setSystemScene(DataIsolationSystemSceneEnum.get(ContextUtil.getSystemScene()));
////            R<List<DataIsolationVo>> listR = projectCoreServiceFeign.queryDataIsolaction(dataIsolationDTO);
////            if (SUCCESS_CODE == listR.getCode()) {
////                ContextUtil.setSubSystemId(listR.getData().get(0).getId());
////            }
//            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
//            ContextUtil.setTenantId(ContextUtil.getProjectId());
//            //切换多数据源
//            ContextUtil.setTenant(tenantUtil.getTenant());
//        } else {
//            throw BizException.wrap(ExceptionCode.USER_NO_ERROR);
//        }


        ContextUtil.setProjectId(commonProjectId);
        ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
        ContextUtil.setTenantId(ContextUtil.getProjectId());
        //切换多数据源
        ContextUtil.setTenant(tenantUtil.getTenant());


        R<UserAccountVo> userAccountVoR = userAccountService.login(userAccountDto);
        //判断用户登录方式
        R<UserAccountVo> resultR = verifyLogin(userAccountVoR, userAccountDto.getSubjectType());


        //并发
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(() -> {
            try {
                if (resultR.getIsSuccess() && userAccountVoR.getData() != null && StringUtils.isNotBlank(userAccountVoR.getData().getRealName())) {
                    //发送站内信
                    InnerSendDTO innerSendDTO = new InnerSendDTO();
                    innerSendDTO.setBusinessType(BusinessEnum.LOGIN_SUCC_CODE.getCode());
                    innerSendDTO.setChannelType(ChannelType.INNER_IM);
                    innerSendDTO.setBusinessId(ContextUtil.getTrace());
                    InnerContentModel innerContentModel = new InnerContentModel();
                    Map<String, Object> contentMap = new HashMap<>();
                    contentMap.put("name", userAccountVoR.getData().getRealName());
//        contentMap.put("ip", userAccountVoR.getData().getRealName());
                    innerContentModel.setContentMap(contentMap);
                    innerSendDTO.setInnerContentModelList(Arrays.asList(innerContentModel));
                    Set<Long> senUserIdList = new HashSet<>();
                    senUserIdList.add(userAccountVoR.getData().getId());
                    innerSendDTO.setSenUserIdList(senUserIdList);
                    msgServiceFeign.sendInnerInMsg(innerSendDTO);
                }
            } catch (Exception e) {

            }
        });


        return resultR;
    }


    /**
     * 登录
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "登录", notes = "登录")
    @PostMapping("/login2")
    @SysLog("登录")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<UserAccountVo> login2(@RequestBody UserAccountDto userAccountDto) {
        log.info("login is " + JSON.toJSONString(userAccountDto));
        //解密
        if (StringUtils.isNotBlank(userAccountDto.getPublicKey())) {
            String privateKey = redisOps.get("privatekey:" + userAccountDto.getPublicKey());
            if (StringUtils.isBlank(privateKey)) {
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
            try {
                userAccountDto.setPassword(RSAEncrypt.decrypt(userAccountDto.getPassword(), privateKey));
                log.info("解密后 login is " + JSON.toJSONString(userAccountDto));
            } catch (Exception e) {
                log.error(e.getMessage());
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
        }

        //检验图形验证码
//        if (StringUtils.isBlank(userAccountDto.getVerifyId())) {
//            throw BizException.wrap(ExceptionCode.CAPTCHA_ERROR);
//        }
        if (StringUtils.isNotBlank(userAccountDto.getVerifyId())) {
            String verifyValue = redisOps.get(userAccountDto.getVerifyId());
            if (StringUtils.isBlank(userAccountDto.getVerifyValue())
                    || StringUtils.isBlank(verifyValue)
                    || !userAccountDto.getVerifyValue().equals(verifyValue)) {
                throw BizException.wrap(ExceptionCode.CAPTCHA_ERROR);
            }
        }

        //检验登录必要参数
        R r = verifyLoginParams(userAccountDto);
        if (SUCCESS_CODE != r.getCode()) {
            return r;
        }
        //全库查询用户信息
//        UserAccountDto userAccountDto2 = new UserAccountDto();
//        userAccountDto2.setName(userAccountDto.getName());
//        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
//        if (userAccountList != null && !userAccountList.isEmpty()) {
//            if (BusinessConstant.NO == userAccountList.get(0).getIsEnabled()) {
//                throw BizException.wrap(ExceptionCode.USER_NO_ENABLED);
//            }
//            //设置项目id
//            ContextUtil.setProjectId(userAccountList.get(0).getProjectId());
//            //设置子系统id
////            DataIsolationDTO dataIsolationDTO = new DataIsolationDTO();
////            dataIsolationDTO.setSystemScene(DataIsolationSystemSceneEnum.get(ContextUtil.getSystemScene()));
////            R<List<DataIsolationVo>> listR = projectCoreServiceFeign.queryDataIsolaction(dataIsolationDTO);
////            if (SUCCESS_CODE == listR.getCode()) {
////                ContextUtil.setSubSystemId(listR.getData().get(0).getId());
////            }
//            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
//            ContextUtil.setTenantId(ContextUtil.getProjectId());
//            //切换多数据源
//            ContextUtil.setTenant(tenantUtil.getTenant());
//        } else {
//            throw BizException.wrap(ExceptionCode.USER_NO_ERROR);
//        }


        ContextUtil.setProjectId(commonProjectId);
        ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
        ContextUtil.setTenantId(ContextUtil.getProjectId());
        //切换多数据源
        ContextUtil.setTenant(tenantUtil.getTenant());


        R<UserAccountVo> userAccountVoR = userAccountService.login(userAccountDto);
        //判断用户登录方式
        R<UserAccountVo> resultR = verifyLogin(userAccountVoR, userAccountDto.getSubjectType());


        //并发
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(() -> {
            try {
                if (resultR.getIsSuccess() && userAccountVoR.getData() != null && StringUtils.isNotBlank(userAccountVoR.getData().getRealName())) {
                    //发送站内信
                    InnerSendDTO innerSendDTO = new InnerSendDTO();
                    innerSendDTO.setBusinessType(BusinessEnum.LOGIN_SUCC_CODE.getCode());
                    innerSendDTO.setChannelType(ChannelType.INNER_IM);
                    innerSendDTO.setBusinessId(ContextUtil.getTrace());
                    InnerContentModel innerContentModel = new InnerContentModel();
                    Map<String, Object> contentMap = new HashMap<>();
                    contentMap.put("name", userAccountVoR.getData().getRealName());
//        contentMap.put("ip", userAccountVoR.getData().getRealName());
                    innerContentModel.setContentMap(contentMap);
                    innerSendDTO.setInnerContentModelList(Arrays.asList(innerContentModel));
                    Set<Long> senUserIdList = new HashSet<>();
                    senUserIdList.add(userAccountVoR.getData().getId());
                    innerSendDTO.setSenUserIdList(senUserIdList);
                    msgServiceFeign.sendInnerInMsg(innerSendDTO);
                }
            } catch (Exception e) {

            }
        });


        return resultR;
    }


    /**
     * 查询用户信息
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "查询用户信息", notes = "查询用户信息")
    @PostMapping("/findUser")
    @SysLog("登录")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<UserAccountVo> findUser(@RequestBody UserAccountDto userAccountDto) {
        log.info("findUser is " + JSON.toJSONString(userAccountDto));
        //检验登录必要参数
        R r = verifyLoginParams(userAccountDto);
        if (SUCCESS_CODE != r.getCode()) {
            return r;
        }
        //全库查询用户信息
        UserAccountDto userAccountDto2 = new UserAccountDto();
        userAccountDto2.setId(userAccountDto.getId());
        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            if (BusinessConstant.NO == userAccountList.get(0).getIsEnabled()) {
                throw BizException.wrap(ExceptionCode.USER_NO_ENABLED);
            }
            //设置项目id
            ContextUtil.setProjectId(userAccountList.get(0).getProjectId());
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
            ContextUtil.setTenantId(ContextUtil.getProjectId());
            //切换多数据源
            ContextUtil.setTenant(tenantUtil.getTenant());
            return R.success(userAccountService.assemblyUserAccount(userAccountList.get(0), userAccountDto));
        } else {
            throw BizException.wrap(ExceptionCode.USER_NO_ERROR);
        }
    }

    /**
     * iam登录
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "iam登录", notes = "iam登录")
    @PostMapping("/iamLogin")
    @SysLog("iam登录")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<UserAccountVo> iamLogin(@RequestBody UserAccountDto userAccountDto) {
        log.info("iamLogin is " + JSON.toJSONString(userAccountDto));
        //检验登录必要参数
        R r = verifyLoginParams(userAccountDto);
        if (SUCCESS_CODE != r.getCode()) {
            return r;
        }

        String token = huaWeiIamUtil.getToken(ContextUtil.getSystemScene(), userAccountDto.getCode());
        HuaWeiAccountDTO huaWeiAccountDTO = huaWeiIamUtil.getUser(ContextUtil.getSystemScene(), token);

        log.info("huaWeiAccountDTO is {}", JSONObject.toJSONString(huaWeiAccountDTO));
        if (huaWeiAccountDTO == null) {
            throw BizException.wrap(ExceptionCode.USER_NO_ERROR);
        }
        if (StringUtils.isBlank(huaWeiAccountDTO.getLoginName())) {
            throw BizException.wrap(ExceptionCode.USER_NO_ERROR);
        }

        //全库查询用户信息
//        UserAccount userAccount = userAccountService.getByIdCache(Long.parseLong(huaWeiAccountDTO.getUid()));
        UserAccountDto userAccountDto2 = new UserAccountDto();
        userAccountDto2.setName(huaWeiAccountDTO.getLoginName());
        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
        log.info("userAccountList is {}", JSONObject.toJSONString(userAccountList));
        UserAccount userAccount = null;
        if (CollectionUtil.isNotEmpty(userAccountList)) {
            userAccount = userAccountList.get(0);
        }

        if (userAccount != null) {
            if (BusinessConstant.NO == userAccount.getIsEnabled()) {
                throw BizException.wrap(ExceptionCode.USER_NO_ENABLED);
            }
            //设置项目id
            ContextUtil.setProjectId(userAccount.getProjectId());
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
            ContextUtil.setTenantId(ContextUtil.getProjectId());
            //切换多数据源
            ContextUtil.setTenant(tenantUtil.getTenant());
        } else {
            throw BizException.wrap(ExceptionCode.USER_NO_ERROR);
        }
        //登陆成功操作
        log.info("subSystemId is {} ", ContextUtil.getSubSystemId());
        UserAccountVo userAccountVo = userAccountService.assemblyUserAccount(userAccount, userAccountDto);

        log.info("userAccountVo is {}", JSONObject.toJSONString(userAccountVo));
        try {
            if (userAccountVo != null && StringUtils.isNotBlank(userAccountVo.getRealName())) {
                //发送站内信
                InnerSendDTO innerSendDTO = new InnerSendDTO();
                innerSendDTO.setBusinessType(BusinessEnum.LOGIN_SUCC_CODE.getCode());
                innerSendDTO.setChannelType(ChannelType.INNER_IM);
                innerSendDTO.setBusinessId(ContextUtil.getTrace());
                InnerContentModel innerContentModel = new InnerContentModel();
                Map<String, Object> contentMap = new HashMap<>();
                contentMap.put("name", userAccountVo.getRealName());
                innerContentModel.setContentMap(contentMap);
                innerSendDTO.setInnerContentModelList(Arrays.asList(innerContentModel));
                Set<Long> senUserIdList = new HashSet<>();
                senUserIdList.add(userAccountVo.getId());
                innerSendDTO.setSenUserIdList(senUserIdList);
                msgServiceFeign.sendInnerInMsg(innerSendDTO);
            }
        } catch (Exception e) {

        }


        return R.success(userAccountVo);
    }


    public R verifyLoginParams(UserAccountDto userAccountDto) {
        //检验登录场景值
        if (StringUtils.isBlank(ContextUtil.getSystemScene())) {
            return R.fail(ExceptionCode.SYS_ORG_NULL);
        }

        return R.success();
    }


    public R<UserAccountVo> verifyLogin(R<UserAccountVo> userAccountVoR, SubjectTypeEnum subjectTypeEnum) {
        if (subjectTypeEnum == null) {
            return userAccountVoR;
        }
        if (userAccountVoR.getCode() == SUCCESS_CODE) {
            //判断用户登录方式
            UserAccountVo userAccountVo = userAccountVoR.getData();
            if (SubjectTypeEnum.ACTOR.getCode().equals(subjectTypeEnum.getCode()) && (userAccountVo.getIsActor() == null || 1 != userAccountVo.getIsActor())) {
//                return R.fail(JWT_PARSER_TOKEN_FAIL);
                throw BizException.wrap(ExceptionCode.JWT_PARSER_TOKEN_FAIL);
            } else if (SubjectTypeEnum.VISITOR.getCode().equals(subjectTypeEnum.getCode()) && (userAccountVo.getIsVisitor() == null || 1 != userAccountVo.getIsVisitor())) {
//                return R.fail(JWT_PARSER_TOKEN_FAIL);
                throw BizException.wrap(ExceptionCode.JWT_PARSER_TOKEN_FAIL);
            }
            return R.success(userAccountVo);
        }
        return userAccountVoR;
    }

    /**
     * 手机号登录
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "手机号登录", notes = "手机号登录")
    @PostMapping("/loginOfMobile")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<UserAccountVo> loginOfMobile(@RequestBody UserAccountDto userAccountDto) {
        CacheKey key = new MobileLoginCodeCacheKeyBuilder().key(userAccountDto.getMobile());
        String code = cacheOps.get(key);
        if (StringUtils.isBlank(code)) {
            return R.fail(ExceptionCode.ERROR_VERIFY);
        }
        if (!code.equals(userAccountDto.getVerifyValue())) {
            return R.fail(ExceptionCode.ERROR_VERIFY);
        }
        //全库查询用户信息
        UserAccountDto userAccountDto2 = new UserAccountDto();
        userAccountDto2.setMobile(userAccountDto.getMobile());
        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            //设置项目id
            ContextUtil.setProjectId(userAccountList.get(0).getProjectId());
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
            ContextUtil.setTenantId(ContextUtil.getProjectId());
            //切换多数据源
            ContextUtil.setTenant(tenantUtil.getTenant());
        }
        R<UserAccountVo> userAccountVoR = userAccountService.loginOfMobile(userAccountDto);
        //判断用户登录方式
        return verifyLogin(userAccountVoR, userAccountDto.getSubjectType());
    }


    /**
     * 获取手机登录验证码
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "获取手机验证码", notes = "获取手机登录验证码")
    @PostMapping("/mobileCode")
    public R mobileCode(@RequestBody UserAccountDto userAccountDto) {
        //解密
        if (StringUtils.isNotBlank(userAccountDto.getPublicKey())) {
            String privateKey = redisOps.get("privatekey:" + userAccountDto.getPublicKey());
            if (StringUtils.isBlank(privateKey)) {
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
            try {
                userAccountDto.setMobile(RSAEncrypt.decrypt(userAccountDto.getMobile(), privateKey));
                log.info("解密后 mobileCode is " + JSON.toJSONString(userAccountDto));
            } catch (Exception e) {
                log.error(e.getMessage());
                throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
            }
        }else{
            throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
        }
        ContextUtil.setProjectId(commonProjectId);
        SmsSendDTO smsSendDTO = new SmsSendDTO();
        smsSendDTO.setBusinessType(BusinessEnum.MOBILE_LOGIN_CODE.getCode());
        smsSendDTO.setChannelType(ChannelType.SMS);
        smsSendDTO.setBusinessId(ContextUtil.getTrace());
        Set<String> mobileSet = new HashSet<>();
        mobileSet.add(userAccountDto.getMobile());
        smsSendDTO.setMobileList(mobileSet);
        SmsContentModel smsContentModel = new SmsContentModel();
        String random = "" + Math.random();
        String code = random.substring(random.length() - 4);
        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("code", code);
        smsContentModel.setContentMap(contentMap);
        smsSendDTO.setSmsContentModelList(Arrays.asList(smsContentModel));
        R r = msgServiceFeign.sendSmsMsg(smsSendDTO);
        if (SUCCESS_CODE == r.getCode()) {
            CacheKey key = new MobileLoginCodeCacheKeyBuilder().key(userAccountDto.getMobile());
            cacheOps.set(key, code);
        }
        return r;
    }

    /**
     * 校验手机验证码
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "校验手机验证码", notes = "校验手机验证码")
    @PostMapping("/validateMobileCode")
    public R validateMobileCode(@RequestBody UserAccountDto userAccountDto) {
        if (StringUtils.isNotBlank(userAccountDto.getCode()) && !"9999".equals(userAccountDto.getCode())) {
            CacheKey key = new MobileLoginCodeCacheKeyBuilder().key(userAccountDto.getMobile());
            String code = cacheOps.get(key);
            if (StringUtils.isBlank(code) || !code.equals(userAccountDto.getCode())) {
                return R.fail(AuthServiceExceptionCode.PHONE_CODE_ERROR);
            }
        }
        return R.success();
    }

    /**
     * 手机号登录（前端）
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "手机号登录（前端）", notes = "手机号登录")
    @PostMapping("/appLoginOfMobile")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<UserAccountVo> appLoginOfMobile(@RequestBody UserAccountDto userAccountDto) {
        //校验手机验证码
//        String verifyValue = redisOps.get(userAccountDto.getVerifyId());
//        if(StringUtils.isBlank(userAccountDto.getVerifyValue()) || !userAccountDto.getVerifyValue().equals(verifyValue)){
//            return R.fail(ExceptionCode.ERROR_VERIFY);
//        }
        //全库查询用户信息
        UserAccountDto userAccountDto2 = new UserAccountDto();
        userAccountDto2.setMobile(userAccountDto.getMobile());
        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            //设置项目id
            ContextUtil.setProjectId(userAccountList.get(0).getProjectId());
//            ContextUtil.setSubSystemId(userAccountList.get(0).getSubsystemId());
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
            ContextUtil.setTenantId(ContextUtil.getProjectId());
            //切换多数据源
            ContextUtil.setTenant(tenantUtil.getTenant());
        }
        R<UserAccountVo> userAccountVoR = userAccountService.loginOfMobile(userAccountDto);
        //判断用户登录方式
        return verifyLogin(userAccountVoR, userAccountDto.getSubjectType());
    }

    /**
     * 邮箱登录
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "邮箱登录", notes = "邮箱登录")
    @PostMapping("/loginOfEmail")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<UserAccountVo> loginOfEmail(@RequestBody UserAccountDto userAccountDto) {
        //校验手机验证码
        //全库查询用户信息
        UserAccountDto userAccountDto2 = new UserAccountDto();
        userAccountDto2.setEmail(userAccountDto.getEmail());
        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            //设置项目id
            ContextUtil.setProjectId(userAccountList.get(0).getProjectId());
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
//            ContextUtil.setSubSystemId(userAccountList.get(0).getSubsystemId());
            ContextUtil.setTenantId(ContextUtil.getProjectId());
            //切换多数据源
            ContextUtil.setTenant(tenantUtil.getTenant());

        }
        R<UserAccountVo> userAccountVoR = userAccountService.loginOfEmail(userAccountDto);
        //判断用户登录方式
        return verifyLogin(userAccountVoR, userAccountDto.getSubjectType());
    }

    /**
     * 登出
     *
     * @param id 用户id
     * @return
     */
    @ApiOperation(value = "登出", notes = "登出")
    @GetMapping("/loginOut")
    public R loginOut(Long id) {
        return userAccountService.loginOut(id);
    }

    /**
     * 查询用户所有角色和菜单
     *
     * @param userId 用户id
     * @return
     */
    @ApiOperation(value = "查询用户所有角色和菜单", notes = "查询用户所有角色和菜单")
    @GetMapping("/findOrgRoleOfUserId")
    @BaseControllerInfo(voGroup = {OrganizationVoGroupClass.findMenuOrFunctionById.class})
    public R<UserAccountVo> findOrgRoleOfUserId(Long userId) {
        UserAccountVo userAccountVo = baseService.findOrgRoleOfUserId(userId);
        return R.success(userAccountVo);

    }


    /**
     * 查询用户所有角色和菜单
     *
     * @return
     */
    @ApiOperation(value = "查询用户所有角色和菜单", notes = "查询用户所有角色和菜单")
    @GetMapping("/getById")
    public R<UserAccountVo> getById(@RequestParam("userId") Long userId, MenuAffiliationEnum
            affiliation, MenuSceneEnum scene) {
        if (userId == null) {
            userId = ContextUtil.getUserId();
        }
        if (affiliation != null) {
            ContextUtil.setMenuAffiliation(affiliation.getCode());
        }
        if (scene != null) {
            ContextUtil.setMenuScene(scene.getCode());
        }
        return baseService.findById(userId);
    }


    /**
     * 查询用户名称
     *
     * @return
     */
    @ApiOperation(value = "查询用户名称", notes = "查询用户名称")
    @GetMapping("/getNameById")
    public R<String> getNameById(@RequestParam("userId") Long userId) {
        UserAccount userAccount = baseService.getByIdCache(userId);
        return R.success(Objects.nonNull(userAccount) ? userAccount.getRealName() : Strings.EMPTY);
    }

    /**
     * 查询用户所有角色和菜单前端用
     *
     * @return
     */
    @ApiOperation(value = "查询用户所有角色和菜单前端用", notes = "查询用户所有角色和菜单前端用")
    @GetMapping("/getByIdLead")
    @SysLog("查询用户所有角色和菜单")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.getByIdLead.class})
    public R<UserAccountVo> getByIdLead(MenuAffiliationEnum affiliation, MenuSceneEnum scene) {
        log.info("getByIdLead is execute");
        if (affiliation != null) {
            ContextUtil.setMenuAffiliation(affiliation.getCode());
        } else {
            ContextUtil.setMenuAffiliation(MenuAffiliationEnum.get(ContextUtil.getSystemScene()).getCode());
//            ContextUtil.setMenuAffiliation(MenuAffiliationEnum.P.getCode());
        }
        if (scene != null) {
            ContextUtil.setMenuScene(scene.getCode());
        } else {
            ContextUtil.setMenuScene(MenuSceneEnum.MANAGE.getCode());
        }
        if(BusinessConstant.YES == ContextUtil.getIsSuperAdmin()){
            //超级管理员拿自身数据，只能拿本系统数据
            ContextUtil.setIsSuperAdmin(BusinessConstant.NO);
        }
        if(BusinessConstant.YES == ContextUtil.getIsAdmin()){
            //超级管理员拿自身数据，只能拿本系统数据
            ContextUtil.setIsAdmin(BusinessConstant.NO);
        }
        return baseService.findById(ContextUtil.getUserId());
    }

    /**
     * 查询用户简单信息
     *
     * @param userId
     * @return
     */
    @ApiOperation(value = "查询用户信息", notes = "查询用户信息")
    @GetMapping("/findSimpleById")
    @SysLog("查询用户信息")
    public R<UserAccountVo> findSimpleById(@RequestParam("userId") Long userId) {
        UserAccount userAccount = baseService.getByIdCache(userId);
        if (userAccount == null) {
            return R.success(null);
        }
        return R.success(baseService.doToVo(userAccount));
    }


    /**
     * 批量查询用户简单信息
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "查询用户信息", notes = "查询用户信息")
    @PostMapping("/querySimpleByIds")
    @SysLog("查询用户信息")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.querySimpleByIds.class})
    public R<List<UserAccountVo>> querySimpleByIds
    (@RequestBody @Validated({UserAccountDto.getByIds.class}) UserAccountDto userAccountDto) {
        return R.success(baseService.listOfUserAccountVo(null, userAccountDto.getUserIds()));
    }


    /**
     * sharding逻辑删除方法 逻辑删除
     * 只做最基本的逻辑删除，如出现其他业务操作请自行添加功能
     *
     * @param ids id
     * @return 是否成功
     */
    @ApiOperation(value = "逻辑删除")
    @DeleteMapping("/removeByIds")
    @SysLog("逻辑删除")
    public R removeByIds(@RequestBody List<Long> ids) {
        return baseService.removeByIds(ids);
    }


    /**
     * 修改用户信息
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "修改用户信息", notes = "修改用户信息")
    @PutMapping("/updateById")
    @SysLog("修改用户信息")
    public R<Boolean> updateById(@RequestBody @Validated({UserAccountDto.updateById.class}) UserAccountDto userAccountDto) {
        //校验用户的登录名和手机号是否重复
        verify(userAccountDto);
        //修改用户组织
        if (CollectionUtil.isNotEmpty(userAccountDto.getOrgIds())) {
            userOrganizationService.removeUserOfOrg(Arrays.asList(userAccountDto.getId()));
            for (Long orgId : userAccountDto.getOrgIds()) {
                organizationService.addUseridOfOrg(orgId, Arrays.asList(userAccountDto.getId()), userAccountDto.getIsLeader());
            }
        } else {
            userOrganizationService.removeUserOfOrg(Arrays.asList(userAccountDto.getId()));
        }
        //修改用户角色
        if (CollectionUtil.isNotEmpty(userAccountDto.getRoleIds())) {
            userRoleService.updUserRole(Arrays.asList(userAccountDto.getId()), userAccountDto.getRoleIds());
        } else {
            userRoleService.removeUserRole(Arrays.asList(userAccountDto.getId()), null);
        }
        return baseService.updateById(userAccountDto);
    }

    /**
     * 校验账号是否冲突
     *
     * @param userAccountDto
     * @return
     */
    public void verify(UserAccountDto userAccountDto) {
        List<UserAccount> userAccountList = userAccountService.queryUserOfregister(userAccountDto);
        if (CollectionUtil.isNotEmpty(userAccountList)) {
            for (UserAccount userAccount : userAccountList) {
                if (!userAccount.getId().equals(userAccountDto.getId())) {
                    if (StringUtils.isNotBlank(userAccountDto.getName()) && userAccountDto.getName().equals(userAccount.getName())) {
                        throw BizException.wrap(ExceptionCode.LOGINNAME_AGAIN);
                    } else if (StringUtils.isNotBlank(userAccountDto.getEmail()) && userAccountDto.getEmail().equals(userAccount.getEmail())) {
                        throw BizException.wrap(ExceptionCode.EMIAL_AGAIN);
                    } else if (StringUtils.isNotBlank(userAccountDto.getMobile()) && userAccountDto.getMobile().equals(userAccount.getMobile())) {
                        throw BizException.wrap(ExceptionCode.MOBILE_AGAIN);
                    } else {
                        throw BizException.wrap(ExceptionCode.USER_MOBILE_AGAIN);
                    }
                }
            }
        }
    }

    /**
     * 修改用户简要信息
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "修改用户信息", notes = "修改用户信息")
    @PutMapping("/updateByIdOfSimple")
    @SysLog("修改用户信息")
    public R<Boolean> updateByIdOfSimple(@RequestBody @Validated({UserAccountDto.updateById.class}) UserAccountDto userAccountDto) {
        return baseService.updateById(userAccountDto);
    }

    /**
     * 添加用户信息
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "添加用户信息", notes = "添加用户信息")
    @PostMapping("/addUser")
    @SysLog("添加用户信息")
    public R<Boolean> addUser(@RequestBody UserAccountDto userAccountDto) {
        return baseService.updateById(userAccountDto);
    }


    /**
     * 设置密码
     *
     * @param userUpdPassParam
     * @return
     */
    @ApiOperation(value = "设置密码", notes = "设置密码")
    @PostMapping("/setPassword")
    @SysLog("设置密码")
    public R<Boolean> setPassword(@RequestBody UserUpdPassParam userUpdPassParam) {
        return baseService.updPassword(userUpdPassParam);
    }


    /**
     * 修改密码
     *
     * @param userUpdPassParam
     * @return
     */
    @ApiOperation(value = "修改密码", notes = "修改密码")
    @PostMapping("/updPassword")
    @SysLog("修改密码")
    public R<Boolean> updPassword(@RequestBody UserUpdPassParam userUpdPassParam) {
        //验证图形验证码
        if (StringUtils.isNotBlank(userUpdPassParam.getVerifyId())) {
            String verifyValue = redisOps.get(userUpdPassParam.getVerifyId());
            if (StringUtils.isBlank(userUpdPassParam.getVerifyValue())
                    || StringUtils.isBlank(verifyValue)
                    || !userUpdPassParam.getVerifyValue().equals(verifyValue)) {
                throw BizException.wrap(ExceptionCode.CAPTCHA_ERROR);
            }
        }

        //密码解密
        String privateKey = redisOps.get("privatekey:" + userUpdPassParam.getPublicKey());
        if (StringUtils.isBlank(privateKey)) {
            throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
        }
        try {
            userUpdPassParam.setOldPassword(RSAEncrypt.decrypt(userUpdPassParam.getOldPassword(), privateKey));
            userUpdPassParam.setNewPassword(RSAEncrypt.decrypt(userUpdPassParam.getNewPassword(), privateKey));
            log.info("解密后 login is " + JSON.toJSONString(userUpdPassParam));
        } catch (Exception e) {
            log.error(e.getMessage());
            throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
        }

        return baseService.updPassword(userUpdPassParam);
    }


    /**
     * 找回密码
     *
     * @param userUpdPassParam
     * @return
     */
    @ApiOperation(value = "找回密码", notes = "找回密码")
    @PostMapping("/updPasswordOfCode")
    @SysLog("找回密码")
    public R<Boolean> updPasswordOfCode(@RequestBody UserUpdPassParam userUpdPassParam) {
        ContextUtil.setProjectId(commonProjectId);
        if (StringUtils.isNotBlank(userUpdPassParam.getCode()) && !"9999".equals(userUpdPassParam.getCode())) {
            CacheKey key = new MobileLoginCodeCacheKeyBuilder().key(userUpdPassParam.getMobile());
            String code = cacheOps.get(key);
            if (!code.equals(userUpdPassParam.getCode())) {
                return R.fail(AuthServiceExceptionCode.PHONE_CODE_ERROR);
            }
        }
        //密码解密
        String privateKey = redisOps.get("privatekey:" + userUpdPassParam.getPublicKey());
        if (StringUtils.isBlank(privateKey)) {
            throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
        }
        try {
            userUpdPassParam.setNewPassword(RSAEncrypt.decrypt(userUpdPassParam.getNewPassword(), privateKey));
            log.info("解密后 login is " + JSON.toJSONString(userUpdPassParam));
        } catch (Exception e) {
            log.error(e.getMessage());
            throw BizException.wrap(ExceptionCode.PRIVATE_KEY);
        }
        return baseService.updPasswordOfCode(userUpdPassParam);
    }

    /**
     * 重置密码
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "重置密码", notes = "重置密码")
    @PostMapping("/initPassword")
    @SysLog("重置密码")
    public R<Boolean> initPassword(@RequestBody UserAccountDto userAccountDto) {
        return baseService.initPassword(userAccountDto.getId());
    }


    /**
     * 根据邮箱和手机号查询用户信息
     *
     * @param mobile 用户id
     * @param email  手机号
     * @return
     */
    @ApiOperation(value = "根据邮箱和手机号查询用户信息", notes = "根据邮箱和手机号查询用户信息")
    @GetMapping("/queryOfPhoneOrEmail")
    @SysLog("根据邮箱和手机号查询用户信息")
    @BaseControllerInfo(voGroup = {OrganizationVoGroupClass.findMenuOrFunctionById.class})
    public R<UserAccount> queryOfPhoneOrEmail(String mobile, String email) {
        UserAccountDto userAccountDto = new UserAccountDto();
        userAccountDto.setEmail(email);
        userAccountDto.setMobile(mobile);
        List<UserAccount> userAccountList = baseService.listOfPhoneOrEmail(userAccountDto);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            return R.success(userAccountList.get(0));
        }
        return R.success(null);
    }


    /**
     * 成为展商，观众
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "成为展商，观众", notes = "成为展商，观众")
    @PostMapping("/initRole")
    public R<UserAccountVo> initRole(@RequestBody UserAccountDto userAccountDto) {
        return baseService.initRole(userAccountDto);
    }


    /**
     * 检验是否有权限
     *
     * @param userId
     * @param permission
     * @return
     */
    @ApiOperation(value = "检验是否有权限", notes = "检验是否有权限")
    @GetMapping("/isPermission")
    public R<Boolean> isPermission(@RequestParam("userId") Long userId, @RequestParam("permission") String[]
            permission, @RequestParam("classPermission") String[] classPermission) {
        return R.success(organizationService.isPermission(userId, permission, classPermission));
    }


    /**
     * 修改关联信息（观众id，展商id，公司id）
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "修改关联信息", notes = "修改关联信息")
    @PostMapping("/updateCorrelationById")
    public R<Boolean> updateCorrelationById(@RequestBody UserAccountDto userAccountDto) {
        UserAccount userAccount = baseService.getByIdCache(userAccountDto.getId());
        if (userAccount == null) {
            return R.success(false);
        }
        UserAccount userAccount1 = new UserAccount();
        BeanUtils.copyProperties(userAccountDto, userAccount1);
        return R.success(baseService.updateById(userAccount1));
    }


    /**
     * 执行查询
     * <p>
     * 可以覆盖后重写查询逻辑
     *
     * @param params 分页参数
     * @return
     */
    @ApiOperation(value = "分页列表查询")
    @PostMapping(value = "/pageVo")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.pageVo.class})
    @SysLog("分页列表查询")
    public R<IPage<UserAccountVo>> pageVo(@RequestBody @Valid PageParams<UserAccountDto> params) {
        // 处理参数
        return R.success(baseService.pageVo(params));
    }


//    /**
//     * 推用户到系统
//     * <p>
//     * 可以覆盖后重写查询逻辑
//     *
//     * @param params 分页参数
//     * @return
//     */
//    @ApiOperation(value = "推用户到系统")
//    @PostMapping(value = "/pushUserToSystem")
//    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.pageVo.class})
//    public R<IPage<UserAccountVo>> pushUserToSystem(@RequestBody UserAccountDto userAccountDto) {
//         addSubSystemUser(userAccountDto);
//        // 处理参数
//        return R.success(baseService.pageVo(params));
//    }


    /**
     * test
     *
     * @return
     */
    @ApiOperation(value = "test2", notes = "检验是否有权限")
    @GetMapping("/test2")
    @SysLog("检验是否有权限")
    @PreAuth("hasAnyPermission('{}test2')")
    public R test2(@RequestParam("userId") Long userId) {
        List<UserAccount> userAccountList = baseService.list();
        List<UserAccountVo> userAccountVoList = baseService.doToVos(userAccountList);
//        for(UserAccountVo userAccountVo : userAccountVoList){
//            userAccountVo.setPayType("corporate_transfer");
//        }
        return R.success(userAccountVoList);
    }

    /**
     * 查询节点的用户信息
     *
     * @param organizationDto 组织Dto
     * @return
     */
    @ApiOperation(value = "查询节点的用户信息", notes = "查询节点的用户信息")
    @PostMapping("/findAllUserOfOrg")
    @BaseControllerInfo(voGroup = {OrganizationVoGroupClass.findAllUserOfOrg.class})
    @SysLog("查询节点的用户信息")
    public R<OrganizationVo> findAllUserOfOrg(@RequestBody OrganizationDTO organizationDto) {
        Organization organization = null;
        //查询组织
        if (organizationDto.getOrgType() != null) {
            organization = organizationService.queryOrgOfType(organizationDto.getOrgType(), organizationDto.getParentId());
        } else if (organizationDto.getOrgId() != null) {
            organization = organizationService.getByIdCache(organizationDto.getOrgId());
        }
        OrganizationVo organizationVo = baseService.findAllUserOfOrg(organization);
        return R.success(organizationVo);
    }


    /**
     * 查询节点的负责人信息
     *
     * @param organizationDto 组织Dto
     * @return
     */
    @ApiOperation(value = "查询节点的负责人信息", notes = "查询节点的用户信息")
    @PostMapping("/findAllLeaderUserOfOrg")
//    @BaseControllerInfo(voGroup = {OrganizationVoGroupClass.findAllLeaderUserOfOrg.class})
    @SysLog("查询节点的负责人信息")
    public R<List<UserAccountVo>> findAllLeaderUserOfOrg(@RequestBody OrganizationDTO organizationDto) {
        Organization organization = null;
        //查询组织
        if (organizationDto.getOrgType() != null) {
            organization = organizationService.queryOrgOfType(organizationDto.getOrgType(), organizationDto.getParentId());
        } else if (organizationDto.getOrgId() != null) {
            organization = organizationService.getByIdCache(organizationDto.getOrgId());
        }
        return R.success(baseService.findAllLeaderUserOfOrg(organization));
    }


    /**
     * 查询节点的用户信息(前端树)
     *
     * @param organizationDto 组织Dto
     * @return
     */
    @ApiOperation(value = "查询节点的用户信息(前端树)", notes = "查询节点的用户信息")
    @PostMapping("/findAllUserOfOrgOfLead")
    @BaseControllerInfo(voGroup = {OrganizationVoGroupClass.findAllUserOfOrg.class})
    @SysLog("查询节点的用户信息")
    public R<DataTreeVo> findAllUserOfOrgOfLead(@RequestBody OrganizationDTO organizationDto) {
        Organization organization = null;
        //查询组织
        if (organizationDto.getOrgType() != null) {
            organization = organizationService.queryOrgOfType(organizationDto.getOrgType(), organizationDto.getParentId());
        } else if (organizationDto.getOrgId() != null) {
            organization = organizationService.getByIdCache(organizationDto.getOrgId());
        }
        OrganizationVo organizationVo = baseService.findAllUserOfOrg(organization);
        DataTreeVo dataTreeVo = organizationService.assemblyTree(organizationVo);
        return R.success(dataTreeVo);
    }


    /**
     * 查询用户权限
     *
     * @param elParam
     * @return
     */
    @ApiOperation(value = "查询用户权限", notes = "查询用户权限")
    @PostMapping("/getPermissionOfUserId")
    public R<List<String>> getPermissionOfUserId(@RequestBody ElParam elParam) {
        //封装全局变量
        HeaderUtil.parseHeaderMap(elParam.getHeaderMap());
        Long userId = Long.parseLong((String) elParam.getObj());
        List<Map> maps = organizationService.loadUserPermission(Arrays.asList(userId));
        if (maps != null && !maps.isEmpty()) {
            Map map = maps.get(0);
            List<String> permissionList = (List<String>) map.get("permissionList");
            return R.success(permissionList);
        }
        return R.success(null);
    }


    /**
     * 查询用户接口权限
     *
     * @param userId
     * @return
     */
    @ApiOperation(value = "查询用户接口权限", notes = "查询用户接口权限")
    @GetMapping("/getIntegerOfUserId")
    public R<List<String>> getPermissionOfUserId(Long userId) {
        if (userId == null) {
            userId = ContextUtil.getUserId();
        }
        //封装全局变量
        List<Map> maps = organizationService.loadUserPermission(Arrays.asList(userId));
        if (maps != null && !maps.isEmpty()) {
            Map map = maps.get(0);
            List<String> interfaceList = (List<String>) map.get("interfaceList");
            return R.success(interfaceList);
        }
        return R.success(null);
    }


    /**
     * 查询用户角色
     *
     * @param userId
     * @return
     */
    @ApiOperation(value = "查询用户角色", notes = "查询用户角色")
    @GetMapping("/getRoleOfUserId")
    public R<List<RoleVo>> getRoleOfUserId(@RequestParam("userId") Long userId) {
        if (userId == null) {
            userId = ContextUtil.getUserId();
        }
        return R.success(baseService.findRoleOfUserId(userId));
    }

    /**
     * 查询用户部门
     *
     * @param userId
     * @return
     */
    @ApiOperation(value = "查询用户部门", notes = "查询用户部门")
    @GetMapping("/getOrgOfUserId")
    public R<List<OrganizationVo>> getOrgOfUserId(@RequestParam("userId") Long userId) {
        if (userId == null) {
            userId = ContextUtil.getUserId();
        }
        return R.success(baseService.findOrgOfUserId(userId));
    }


    /**
     * 批量查询用户ID
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "批量查询用户ID", notes = "批量查询用户ID")
    @PostMapping("/queryIds")
    public R<List<Long>> queryIds(@RequestBody UserAccountDto userAccountDto) {
        if (CollectionUtil.isNotEmpty(userAccountDto.getOrgIds())) {
            List<UserOrganizationVo> userOrganizationVos = userOrganizationService.queryUserVoByOrg(userAccountDto.getOrgIds());
            if (CollectionUtil.isNotEmpty(userOrganizationVos)) {
                return R.success(userOrganizationVos.stream().map(UserOrganizationVo::getUserId).collect(Collectors.toList()));
            }
        } else if (userAccountDto.getIsFindAll()) {
            UserAccount userAccount = new UserAccount();
            //组装系统id
            userAccountService.assembleSubSystem(userAccount, BusinessConstant.YES);
            //组装teamid
            userAccountService.assembleTeam(userAccount);
            QueryWrap<UserAccount> queryWrapper = Wraps.q(userAccount);
            queryWrapper.select("id");
            queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
            queryWrapper.lambda().eq(UserAccount::getIsEnabled, BusinessConstant.DELETE_YES);
            List<UserAccount> userAccountList = userAccountService.list(queryWrapper);
            if (CollectionUtil.isNotEmpty(userAccountList)) {
                return R.success(userAccountList.stream().map(UserAccount::getId).collect(Collectors.toList()));
            }
        }
        return R.success(null);
    }


    /**
     * 批量查询用户手机号
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "批量查询用户手机号", notes = "批量查询用户手机号")
    @PostMapping("/queryMobiles")
    public R<Map<Long, String>> queryMobiles(@RequestBody UserAccountDto userAccountDto) {
        if (CollectionUtil.isNotEmpty(userAccountDto.getUserIds())) {
            List<UserAccount> userAccountList = userAccountService.listOfUserAccount(null, userAccountDto.getUserIds());
            if (CollectionUtil.isNotEmpty(userAccountList)) {
                Map<Long, String> map = new HashMap<>();
                for (UserAccount userAccount : userAccountList) {
                    if (StringUtils.isNotBlank(userAccount.getMobile())) {
                        map.put(userAccount.getId(), userAccount.getMobile());
                    }
                }
                return R.success(map);
            }
        }
        return R.success(null);
    }


    /**
     * test
     *
     * @return
     */
    @ApiOperation(value = "test2", notes = "检验是否有权限")
    @GetMapping("/test3")
    public R test3(Long id) {
        UserAccount userAccount = new UserAccount();
        userAccount.setId(id);
        List<UserAccount> userAccountList = businessMapper.test3(userAccount);
        return R.success(userAccountList);
    }


    public RoleVo findParentRole(RoleDTO roleDTO) {
        Role role = new Role();
        BeanUtils.copyProperties(roleDTO, role);
        List<RoleVo> roleVoList = roleService.doToVos(roleService.list(role, null, null));
        if (CollectionUtil.isEmpty(roleVoList)) {
            throw BizException.wrap(AuthServiceExceptionCode.NOT_ROLE_MENU_NULL);
        }
        for (RoleVo roleVo : roleVoList) {
            //查询菜单集合
            List<Long> menuIds = roleService.findMenuIdById(roleVo.getId());
            roleVo.setMenuIds(menuIds);
        }
        return roleVoList.get(0);
    }

    /**
     * 注册服务商功能
     *
     * @param registerDTO
     * @return
     */
    @ApiOperation(value = "注册服务商功能", notes = "注册服务商功能")
    @PostMapping("/registerServiceProvider")
    @SysLog("注册服务商功能")
    public R registerServiceProvider(@RequestBody RegisterDTO registerDTO) {
        log.info("执行注册服务商功能 服务  参数：{}", JSONObject.toJSONString(registerDTO));
        if (registerDTO.getUserAccountDto().getProducerId() == null
                && registerDTO.getUserAccountDto().getCourtId() == null
                && registerDTO.getUserAccountDto().getMatingId() == null
                && registerDTO.getUserAccountDto().getTransportId() == null) {
            throw BizException.wrap(AuthServiceExceptionCode.PRODUCE_ID_NULL);
        }
        ContextUtil.setTeamId(null);
        if (registerDTO.getUserAccountDto().getProducerId() != null) {
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(DataIsolationSystemSceneEnum.P_COMPOSITE_PRODUCER.getCode()));
        } else if (registerDTO.getUserAccountDto().getCourtId() != null) {
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode()));
        } else if (registerDTO.getUserAccountDto().getMatingId() != null) {
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(DataIsolationSystemSceneEnum.P_COMPOSITE_MATING.getCode()));
        } else if (registerDTO.getUserAccountDto().getTransportId() != null) {
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(DataIsolationSystemSceneEnum.P_COMPOSITE_TRANSPORT.getCode()));
        }
        RoleDTO roleDTO = new RoleDTO();
        roleDTO.setRoleType(registerDTO.getRoleDTO().getRoleType());
        RoleVo parentRoleVO = findParentRole(roleDTO);
        log.info("查询顶级角色信息 is {}", JSONObject.toJSONString(parentRoleVO));
        ContextUtil.setIsSystemOlationIgnore(false);
        ContextUtil.setTeamId(registerDTO.getTeamId());
        //创建服务商的顶级组织
        OrganizationDTO organizationDTO = registerDTO.getOrganizationDTO();
        Organization organization = new Organization();
        organization.setOrgType(organizationDTO.getOrgType());
        organization.setParentId(BusinessConstant.parentId);
//        organization.setTeamId(registerDTO.getTeamId());
        List<Organization> organizationList = organizationService.listOfOrganization(organization, null);
        if (CollectionUtil.isEmpty(organizationList)) {
            R<Organization> organizationR = organizationService.createOrg(organizationDTO);
            log.info("创建服务商的顶级组织 is {}", JSONObject.toJSONString(organizationR));
        }

        //创建服务商的角色
        RoleDTO serviceRole = new RoleDTO();
        serviceRole.setName(registerDTO.getRoleDTO().getName());
        serviceRole.setMenuIds(parentRoleVO.getMenuIds());
        serviceRole.setBusinessTag(registerDTO.getRoleDTO().getBusinessTag());
        serviceRole.setSourceRoleId(parentRoleVO.getId());
//        R<Role> roleR = roleService.createRole(serviceRole);
        R<Role> roleR = roleService.createRoleOfRepetition(serviceRole);
        log.info("创建角色 is {}", JSONObject.toJSONString(roleR));
        Long roleId = null;
        if (roleR.getIsSuccess()) {
            roleId = roleR.getData().getId();
        } else {
            if (AuthServiceExceptionCode.ROLE_AGAIN.getCode() == roleR.getCode()) {
                //角色已存在,查询角色
                Role role1 = new Role();
                BeanUtils.copyProperties(serviceRole, role1);
                List<Role> roleList = roleService.list(role1, null, null);
                if (CollectionUtils.isNotEmpty(roleList)) {
                    roleId = roleList.get(0).getId();
                }
            }
        }
        log.info("角色id is {}", roleId);
        //给用户添加基础角色
        UserRole userRole = new UserRole();
        userRole.setRoleId(roleId);
        userRole.setUserId(registerDTO.getUserAccountDto().getId());
        List<UserRole> userRoleList = userRoleService.list(userRole, null, null);
        if (CollectionUtil.isEmpty(userRoleList)) {
            R userRoleR = userRoleService.addUserRole(Arrays.asList(registerDTO.getUserAccountDto().getId()), Arrays.asList(roleId));
            if (!userRoleR.getIsSuccess()) {
                throw BizException.wrap(userRoleR.getCode(), userRoleR.getMsg());
            }
        }
        //更新数据
        UserAccount userAccount1 = new UserAccount();
        BeanUtils.copyProperties(registerDTO.getUserAccountDto(), userAccount1);
        userAccount1.setIsPrimaryAccount(BusinessConstant.YES);
        userAccountService.updateById(userAccount1);
        return R.success();
    }


    /**
     * 获取token
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "获取token", notes = "获取token")
    @PostMapping("/getToken")
    @SysLog("获取token")
    public R<String> getToken(@RequestBody UserAccountDto userAccountDto) {
        JwtUserInfo jwtUserInfo = new JwtUserInfo();
        jwtUserInfo.setProjectId(userAccountDto.getProjectId());
        jwtUserInfo.setSubsystemId(userAccountDto.getSubsystemId());
        jwtUserInfo.setUserId(userAccountDto.getId());
        jwtUserInfo.setName(userAccountDto.getName());
        //系统场景
        jwtUserInfo.setSystemScene(userAccountDto.getSystemScene());
        AuthInfo authInfo = jwtService.build(jwtUserInfo);
        return R.success(authInfo.getToken());
    }


    /**
     * 通过账号拿token
     *
     * @param loginName
     * @return
     */
    @ApiOperation(value = "通过账号拿用户信息和token", notes = "通过账号拿用户信息和token")
    @GetMapping("/getTokenOrLoginUser")
    @SysLog("通过账号拿token")
    public R<UserAccountVo> getUserAccountOfLoginUser(String loginName) {
        log.info("getTokengetTokenOrLoginUser is " + loginName);
        //全库查询用户信息
        UserAccountDto userAccountDto2 = new UserAccountDto();
        userAccountDto2.setName(loginName);
        ContextUtil.setProjectId(commonProjectId);
        List<UserAccount> userAccountList = userAccountService.getUserByNameAllDb(userAccountDto2);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            if (BusinessConstant.NO == userAccountList.get(0).getIsEnabled()) {
                throw BizException.wrap(ExceptionCode.USER_NO_ENABLED);
            }
            ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
            ContextUtil.setTenantId(ContextUtil.getProjectId());
            //切换多数据源
            ContextUtil.setTenant(tenantUtil.getTenant());
            //加载token信息
            UserAccountVo userAccountVo = userAccountService.doToVo(userAccountList.get(0));
            userAccountService.loadToken(userAccountVo, null);
            return R.success(userAccountVo);
        } else {
            throw BizException.wrap(ExceptionCode.USER_NO_ERROR);
        }
    }


    /**
     * 获取小程序token
     *
     * @param userAccountDto
     * @return
     */
    @ApiOperation(value = "获取小程序token", notes = "获取小程序token")
    @PostMapping("/getTokenOfMini")
    @SysLog("获取小程序token")
    public R<String> getTokenOfMini(@RequestBody @Validated({UserAccountDto.getTokenOfMini.class}) UserAccountDto userAccountDto) {
        JwtUserInfo jwtUserInfo = new JwtUserInfo();
        if (userAccountDto.getProjectId() == null) {
            userAccountDto.setProjectId(commonProjectId);
        }
        ContextUtil.setProjectId(userAccountDto.getProjectId());
        //组装系统id
        //服务商类型 #{
        // BUILD_SERVICE_PROVIDER:搭建服务商;
        // MAIN_TRANSPORT_SERVICE_PROVIDER:主运服务商;
        // HOME_SERVICE_PROVIDER:主场服务商;
        // MATCHING_SERVICE_PROVIDER:配套服务商
        // }
        if ("BUILD_SERVICE_PROVIDER".equals(userAccountDto.getServiceProviderType())) {
            ContextUtil.setSystemScene(OrganizationOrgTypeEnum.P_COMPOSITE_PRODUCER.getCode());

        } else if ("MAIN_TRANSPORT_SERVICE_PROVIDER".equals(userAccountDto.getServiceProviderType())) {
            ContextUtil.setSystemScene(OrganizationOrgTypeEnum.P_COMPOSITE_TRANSPORT.getCode());
        } else if ("HOME_SERVICE_PROVIDER".equals(userAccountDto.getServiceProviderType())) {
            ContextUtil.setSystemScene(OrganizationOrgTypeEnum.P_COMPOSITE_COURT.getCode());
        } else if ("MATCHING_SERVICE_PROVIDER".equals(userAccountDto.getServiceProviderType())) {
            ContextUtil.setSystemScene(OrganizationOrgTypeEnum.P_COMPOSITE_MATING.getCode());
        }
        if (StringUtils.isBlank(ContextUtil.getSystemScene())) {
            ContextUtil.setSystemScene(userAccountDto.getSystemScene());
        }
        jwtUserInfo.setSubsystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
        jwtUserInfo.setProjectId(userAccountDto.getProjectId());
        if (userAccountDto.getServiceProviderId() != null) {
            jwtUserInfo.setTeamId(userAccountDto.getServiceProviderId());
        }

        AuthInfo authInfo = jwtService.build(jwtUserInfo);
        return R.success(authInfo.getToken());
    }


    /**
     * 主办手机号登录
     *
     * @param userAccountDto 用户登录实体
     * @return
     */
    @ApiOperation(value = "主办手机号登录", notes = "主办手机号登录")
    @PostMapping("/loginOfMobileOfSponsor")
    @BaseControllerInfo(voGroup = {UserAccountVoGroupClass.login.class})
    public R<String> loginOfMobileOfSponsor(@RequestBody UserAccountDto userAccountDto) {
        CacheKey key = new MobileLoginCodeCacheKeyBuilder().key(userAccountDto.getMobile());
        String code = cacheOps.get(key);
        if (StringUtils.isBlank(code)) {
            return R.fail(ExceptionCode.ERROR_VERIFY);
        }
        if (!code.equals(userAccountDto.getVerifyValue()) && !"9999".equals(code)) {
            return R.fail(ExceptionCode.ERROR_VERIFY);
        }

        ContextUtil.setSystemScene(OrganizationOrgTypeEnum.P_COMPOSITE_VENUE.getCode());
        ContextUtil.setProjectId(commonProjectId);
        ContextUtil.setSubSystemId(dataIsolactionHandler.assmableSystemId(ContextUtil.getSystemScene()));
        ContextUtil.setTenantId(ContextUtil.getProjectId());


        JwtUserInfo jwtUserInfo = new JwtUserInfo();
        jwtUserInfo.setProjectId(commonProjectId);
        jwtUserInfo.setSubsystemId(ContextUtil.getSubSystemId());
//        jwtUserInfo.setUserId(userAccountVo.getId());
//        jwtUserInfo.setName(userAccountVo.getName());
        //系统场景
        jwtUserInfo.setSystemScene(ContextUtil.getSystemScene());
//        jwtUserInfo.setRealName(userAccountVo.getRealName());
//        jwtUserInfo.setIsAdmin(userAccountVo.getIsAdmin());
//        jwtUserInfo.setIsSuperAdmin(userAccountVo.getIsSuperAdmin());
//        jwtUserInfo.setIsSuperAdmin(assembleIsSuperAdminOfSystemScene(userAccountVo));
        AuthInfo authInfo = jwtService.build(jwtUserInfo);
        //判断用户登录方式
        return R.success(authInfo.getToken());
    }


    /**
     * 加载用户接口权限信息
     *
     * @param
     * @return
     */
    @ApiOperation(value = "加载用户接口权限信息", notes = "加载用户接口权限信息")
    @GetMapping("/loadUserInterface")
    public R loadUserInterface(Long userId) {
        organizationService.loadUserPermission(Arrays.asList(userId));
        //判断用户登录方式
        return R.success();
    }


    /**
     * 修改加密方式
     *
     * @param
     * @return
     */
//    @ApiOperation(value = "修改加密方式", notes = "修改加密方式")
//    @GetMapping("/executeEncrypt")
//    public R executeEncrypt(Long userId) {
//        UserAccount userAccount = new UserAccount();
//        if (userId != null) {
//            userAccount.setId(userId);
//        }
//        List<UserAccount> userAccountList = baseService.listOfUserAccount(userAccount, null);
//        //修改加密数据
//        if(CollectionUtil.isNotEmpty(userAccountList)){
//            for(UserAccount userAccount1 : userAccountList){
//                userAccount1.setMobile(TypeHandlerUtil.oldDecrypt(userAccount1.getMobile()));
//                userAccount1.setPassword(TypeHandlerUtil.oldDecrypt(userAccount1.getPassword()));
//                userAccount1.setIdCard(TypeHandlerUtil.oldDecrypt(userAccount1.getIdCard()));
//                baseService.updateById(userAccount1);
//            }
//        }
//
//        return R.success();
//    }

    /**
     * 创建雪花id
     * @return
     */
    @ApiOperation(value = "创建雪花id", notes = "创建雪花id")
    @GetMapping("/nexId")
    public Long nexId() {
        Long l = System.currentTimeMillis();
        for(int i=0;i<5000;i++){
            snowFlakeRole.findUidSimple();
//            System.out.println(snowFlakeRole.findUidSimple());
        }
        System.out.println(snowFlakeRole.findUidSimple());
        System.out.println(System.currentTimeMillis()-l);
        return snowFlakeRole.findUidSimple();
    }
}
